home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / LIB / GLUT / glut_cindex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  7.6 KB  |  253 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994, 1996, 1997. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. #include <stdlib.h>
  9. #include "glutint.h"
  10.  
  11. #define CLAMP(i) ((i) > 1.0 ? 1.0 : ((i) < 0.0 ? 0.0 : (i)))
  12.  
  13. /* CENTRY */
  14. void APIENTRY
  15. glutSetColor(int ndx, GLfloat red, GLfloat green, GLfloat blue)
  16. {
  17.   GLUTcolormap *cmap, *newcmap;
  18.   XVisualInfo *vis;
  19.   XColor color;
  20.   int i;
  21.  
  22.   if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
  23.     cmap = __glutCurrentWindow->colormap;
  24.     vis = __glutCurrentWindow->vis;
  25.   } else {
  26.     cmap = __glutCurrentWindow->overlay->colormap;
  27.     vis = __glutCurrentWindow->overlay->vis;
  28.     if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
  29.       __glutWarning(
  30.         "glutSetColor: cannot set color of overlay transparent index %d\n",
  31.         ndx);
  32.       return;
  33.     }
  34.   }
  35.  
  36.   if (!cmap) {
  37.     __glutWarning("glutSetColor: current window is RGBA");
  38.     return;
  39.   }
  40. #if defined(_WIN32)
  41.   if (ndx >= 256 ||     /* always assume 256 colors on Win32 */
  42. #else
  43.   if (ndx >= vis->visual->map_entries ||
  44. #endif
  45.     ndx < 0) {
  46.     __glutWarning("glutSetColor: index %d out of range", ndx);
  47.     return;
  48.   }
  49.   if (cmap->refcnt > 1) {
  50.     newcmap = __glutAssociateNewColormap(vis);
  51.     cmap->refcnt--;
  52.     /* Wouldn't it be nice if XCopyColormapAndFree could be
  53.        told not to free the old colormap's entries! */
  54.     for (i = cmap->size - 1; i >= 0; i--) {
  55.       if (i == ndx) {
  56.         /* We are going to set this cell shortly! */
  57.         continue;
  58.       }
  59.       if (cmap->cells[i].component[GLUT_RED] >= 0.0) {
  60.         color.pixel = i;
  61.         newcmap->cells[i].component[GLUT_RED] =
  62.           cmap->cells[i].component[GLUT_RED];
  63.         color.red = (GLfloat) 0xffff *
  64.           cmap->cells[i].component[GLUT_RED];
  65.         newcmap->cells[i].component[GLUT_GREEN] =
  66.           cmap->cells[i].component[GLUT_GREEN];
  67.         color.green = (GLfloat) 0xffff *
  68.           cmap->cells[i].component[GLUT_GREEN];
  69.         newcmap->cells[i].component[GLUT_BLUE] =
  70.           cmap->cells[i].component[GLUT_BLUE];
  71.         color.blue = (GLfloat) 0xffff *
  72.           cmap->cells[i].component[GLUT_BLUE];
  73.         color.flags = DoRed | DoGreen | DoBlue;
  74. #if defined(_WIN32)
  75.         if (IsWindowVisible(__glutCurrentWindow->win)) {
  76.           XHDC = __glutCurrentWindow->hdc;
  77.         } else {
  78.           XHDC = 0;
  79.         }
  80. #endif
  81.         XStoreColor(__glutDisplay, newcmap->cmap, &color);
  82.       } else {
  83.         /* Leave unallocated entries unallocated. */
  84.       }
  85.     }
  86.     cmap = newcmap;
  87.     if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
  88.       __glutCurrentWindow->colormap = cmap;
  89.       __glutCurrentWindow->cmap = cmap->cmap;
  90.     } else {
  91.       __glutCurrentWindow->overlay->colormap = cmap;
  92.       __glutCurrentWindow->overlay->cmap = cmap->cmap;
  93.     }
  94.     XSetWindowColormap(__glutDisplay,
  95.       __glutCurrentWindow->renderWin, cmap->cmap);
  96.  
  97. #if !defined(_WIN32)
  98.     {
  99.       GLUTwindow *toplevel;
  100.  
  101.       toplevel = __glutToplevelOf(__glutCurrentWindow);
  102.       if (toplevel->cmap != cmap->cmap) {
  103.         __glutPutOnWorkList(toplevel, GLUT_COLORMAP_WORK);
  104.       }
  105.     }
  106. #endif
  107.   }
  108.   color.pixel = ndx;
  109.   red = CLAMP(red);
  110.   cmap->cells[ndx].component[GLUT_RED] = red;
  111.   color.red = (GLfloat) 0xffff *red;
  112.   green = CLAMP(green);
  113.   cmap->cells[ndx].component[GLUT_GREEN] = green;
  114.   color.green = (GLfloat) 0xffff *green;
  115.   blue = CLAMP(blue);
  116.   cmap->cells[ndx].component[GLUT_BLUE] = blue;
  117.   color.blue = (GLfloat) 0xffff *blue;
  118.   color.flags = DoRed | DoGreen | DoBlue;
  119. #if defined(_WIN32)
  120.   if (IsWindowVisible(__glutCurrentWindow->win)) {
  121.     XHDC = __glutCurrentWindow->hdc;
  122.   } else {
  123.     XHDC = 0;
  124.   }
  125. #endif
  126.   XStoreColor(__glutDisplay, cmap->cmap, &color);
  127. }
  128.  
  129. GLfloat APIENTRY
  130. glutGetColor(int ndx, int comp)
  131. {
  132.   GLUTcolormap *colormap;
  133.   XVisualInfo *vis;
  134.  
  135.   if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
  136.     colormap = __glutCurrentWindow->colormap;
  137.     vis = __glutCurrentWindow->vis;
  138.   } else {
  139.     colormap = __glutCurrentWindow->overlay->colormap;
  140.     vis = __glutCurrentWindow->overlay->vis;
  141.     if (ndx == __glutCurrentWindow->overlay->transparentPixel) {
  142.       __glutWarning("glutGetColor: requesting overlay transparent index %d\n",
  143.         ndx);
  144.       return -1.0;
  145.     }
  146.   }
  147.  
  148.   if (!colormap) {
  149.     __glutWarning("glutGetColor: current window is RGBA");
  150.     return -1.0;
  151.   }
  152. #if defined(_WIN32)
  153. #define OUT_OF_RANGE_NDX(ndx) (ndx >= 256 || ndx < 0)
  154. #else
  155. #define OUT_OF_RANGE_NDX(ndx) (ndx >= vis->visual->map_entries || ndx < 0)
  156. #endif
  157.   if (OUT_OF_RANGE_NDX(ndx)) {
  158.     __glutWarning("glutGetColor: index %d out of range", ndx);
  159.     return -1.0;
  160.   }
  161.   return colormap->cells[ndx].component[comp];
  162. }
  163.  
  164. void APIENTRY
  165. glutCopyColormap(int winnum)
  166. {
  167.   GLUTwindow *window = __glutWindowList[winnum - 1];
  168.   GLUTcolormap *oldcmap, *newcmap;
  169.   XVisualInfo *dstvis;
  170.  
  171.   if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
  172.     oldcmap = __glutCurrentWindow->colormap;
  173.     dstvis = __glutCurrentWindow->vis;
  174.     newcmap = window->colormap;
  175.   } else {
  176.     oldcmap = __glutCurrentWindow->overlay->colormap;
  177.     dstvis = __glutCurrentWindow->overlay->vis;
  178.     if (!window->overlay) {
  179.       __glutWarning("glutCopyColormap: window %d has no overlay", winnum);
  180.       return;
  181.     }
  182.     newcmap = window->overlay->colormap;
  183.   }
  184.  
  185.   if (!oldcmap) {
  186.     __glutWarning("glutCopyColormap: destination colormap must be color index");
  187.     return;
  188.   }
  189.   if (!newcmap) {
  190.     __glutWarning(
  191.       "glutCopyColormap: source colormap of window %d must be color index",
  192.       winnum);
  193.     return;
  194.   }
  195.   if (newcmap == oldcmap) {
  196.     /* Source and destination are the same; now copy needed. */
  197.     return;
  198.   }
  199. #if !defined(_WIN32)
  200.   /* Play safe: compare visual IDs, not Visual*'s. */
  201.   if (newcmap->visual->visualid == oldcmap->visual->visualid) {
  202. #endif
  203.     /* Visuals match!  "Copy" by reference...  */
  204.     __glutFreeColormap(oldcmap);
  205.     newcmap->refcnt++;
  206.     if (__glutCurrentWindow->renderWin == __glutCurrentWindow->win) {
  207.       __glutCurrentWindow->colormap = newcmap;
  208.       __glutCurrentWindow->cmap = newcmap->cmap;
  209.     } else {
  210.       __glutCurrentWindow->overlay->colormap = newcmap;
  211.       __glutCurrentWindow->overlay->cmap = newcmap->cmap;
  212.     }
  213.     XSetWindowColormap(__glutDisplay, __glutCurrentWindow->renderWin,
  214.       newcmap->cmap);
  215. #if !defined(_WIN32)
  216.     __glutPutOnWorkList(__glutToplevelOf(window), GLUT_COLORMAP_WORK);
  217.   } else {
  218.     GLUTcolormap *copycmap;
  219.     XColor color;
  220.     int i, last;
  221.  
  222.     /* Visuals different - need a distinct X colormap! */
  223.     copycmap = __glutAssociateNewColormap(dstvis);
  224.     /* Wouldn't it be nice if XCopyColormapAndFree could be
  225.        told not to free the old colormap's entries! */
  226.     last = newcmap->size;
  227.     if (last > copycmap->size) {
  228.       last = copycmap->size;
  229.     }
  230.     for (i = last - 1; i >= 0; i--) {
  231.       if (newcmap->cells[i].component[GLUT_RED] >= 0.0) {
  232.         color.pixel = i;
  233.         copycmap->cells[i].component[GLUT_RED] =
  234.           newcmap->cells[i].component[GLUT_RED];
  235.         color.red = (GLfloat) 0xffff *
  236.           newcmap->cells[i].component[GLUT_RED];
  237.         copycmap->cells[i].component[GLUT_GREEN] =
  238.           newcmap->cells[i].component[GLUT_GREEN];
  239.         color.green = (GLfloat) 0xffff *
  240.           newcmap->cells[i].component[GLUT_GREEN];
  241.         copycmap->cells[i].component[GLUT_BLUE] =
  242.           newcmap->cells[i].component[GLUT_BLUE];
  243.         color.blue = (GLfloat) 0xffff *
  244.           newcmap->cells[i].component[GLUT_BLUE];
  245.         color.flags = DoRed | DoGreen | DoBlue;
  246.         XStoreColor(__glutDisplay, copycmap->cmap, &color);
  247.       }
  248.     }
  249.   }
  250. #endif
  251. }
  252. /* ENDCENTRY */
  253.